package com.xayq.orap.oauth.controller;

import org.apache.oltu.oauth2.as.request.OAuthAuthzRequest;
import org.apache.oltu.oauth2.as.response.OAuthASResponse;
import org.apache.oltu.oauth2.common.error.OAuthError;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.apache.oltu.oauth2.common.message.types.ResponseType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.xayq.orap.oauth.MyOAuthAuthzRequest;
import com.xayq.orap.oauth.authorize.CodeAuthorizeHandler;
import com.xayq.orap.oauth.authorize.TokenAuthorizeHandler;
import com.xayq.orap.utils.CommonUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@Controller
public class OAuthAuthorizeController {


    private static final Logger LOG = LoggerFactory.getLogger(OAuthAuthorizeController.class);
    
    @Autowired
    private CodeAuthorizeHandler codeAuthorizeHandler;
    @Autowired
    private TokenAuthorizeHandler tokenAuthorizeHandler;

    /**
     * Must handle the grant_type as follow:
     * grant_type="authorization_code" -> response_type="code"
     * ?response_type=code&scope=read,write&client_id=[client_id]&client_secret=[client_secret]&redirect_uri=[redirect_uri]&state=[state]
     * <p/>
     * grant_type="implicit"   -> response_type="token"
     * ?response_type=token&scope=read,write&client_id=[client_id]&client_secret=[client_secret]&redirect_uri=[redirect_uri]
     * <p/>
     *
     * @param request  HttpServletRequest
     * @param response HttpServletResponse
     */
    @RequestMapping("/authorize")
    public void authorize(HttpServletRequest request, HttpServletResponse response) throws Exception {

        try {
        	MyOAuthAuthzRequest oauthRequest = new MyOAuthAuthzRequest(request);


            if (oauthRequest.isCode()) {
                LOG.debug("Go to  response_type = 'code' handler: {}", codeAuthorizeHandler);
                codeAuthorizeHandler.handle(oauthRequest, response);

            } else if (oauthRequest.isToken()) {
                LOG.debug("Go to response_type = 'token' handler: {}", tokenAuthorizeHandler);
                tokenAuthorizeHandler.handle(oauthRequest, response);

            } else {
                unsupportResponseType(oauthRequest, response);
            }

        } catch (OAuthProblemException e) {
            //exception
            OAuthResponse oAuthResponse = OAuthASResponse
                    .errorResponse(HttpServletResponse.SC_FOUND)
                    .location(e.getRedirectUri())
                    .error(e)
                    .buildJSONMessage();
            CommonUtils.writeOAuthJsonResponse(response, oAuthResponse);
        }


    }


    private void unsupportResponseType(OAuthAuthzRequest oauthRequest, HttpServletResponse response) throws OAuthSystemException {
        String responseType = oauthRequest.getResponseType();
        LOG.debug("Unsupport response_type '{}' by client_id '{}'", responseType, oauthRequest.getClientId());

        OAuthResponse oAuthResponse = OAuthResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
                .setError(OAuthError.CodeResponse.UNSUPPORTED_RESPONSE_TYPE)
                .setErrorDescription("Unsupport response_type '" + responseType + "'")
                .buildJSONMessage();
        CommonUtils.writeOAuthJsonResponse(response, oAuthResponse);
    }


//    @RequestMapping(value = "oauth_login")
//    public String oauthLogin() {
//        return "views/oauth_login";
//    }
//
//
//    @RequestMapping(value = "oauth_approval")
//    public String oauthApproval() {
//        return "views/oauth_approval";
//    }


}